<?php
/**
 * 易优CMS
 * ============================================================================
 * 版权所有 2016-2028 海南赞赞网络科技有限公司，并保留所有权利。
 * 网站地址: http://www.eyoucms.com
 * ----------------------------------------------------------------------------
 * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
 * ============================================================================
 * Author: 陈风任 <491085389@qq.com>
 * Date: 2020-05-07
 */

namespace app\api\model\v1;

use think\Db;
use think\Cache;
use think\Config;

/**
 * 微信小程序商城订单维权模型
 */
load_trait('controller/Jump');

class ShopOrderService extends UserBase
{
    use \traits\controller\Jump;

    //初始化
    protected function initialize()
    {
        // 需要调用`Model`的`initialize`方法
        parent::initialize();
    }

    // 查询订单内的指定的某个商品，判断是否已申请售后或已评价商品
    public function getOrderGoodsDetect($post = [])
    {
        // 查询商品
        $where = [
            'users_id' => $this->users_id,
            'order_id' => $post['order_id'],
            'details_id' => $post['details_id'],
            'product_id' => $post['product_id']
        ];
        $field = 'details_id, order_id, users_id, product_id, apply_service, is_comment';
        $orderGoods = Db::name("shop_order_details")->where($where)->field($field)->find();
        if (empty($orderGoods)) $this->error('订单商品不存在');
        $orderGoods['service_id'] = 0;

        // 检测商品是否可以进行下一步操作
        if ('service' == $post['use']) {
            if (!empty($orderGoods['apply_service'])) {
                $where['status'] = ['NEQ', 8];
                $orderGoods['service_id'] = Db::name('shop_order_service')->where($where)->getField('service_id');
            }
        } else if ('comment' == $post['use']) {
            if (!empty($orderGoods['is_comment'])) {
                $url = strval('/pages/article/view?aid=' . $post['product_id']);
                $this->success('订单商品已完成评价', $url, false);
            }
        }

        // 返回信息
        $this->success('检测完成', null, $orderGoods);
    }

    // 查询售后服务单列表
    public function getOrderGoodsServiceList($post = [])
    {
        $where = [
            'a.status' => ['NOT IN', [8]],
            'a.users_id' => $this->users_id,
        ];
        if (!empty($post['serviceStatus']) && 1 == $post['serviceStatus']) {
            $where['a.status'] = ['IN', [1, 2, 4, 5]];
        } else if (!empty($post['serviceStatus']) && 2 == $post['serviceStatus']) {
            $where['a.status'] = ['IN', [6, 7]];
        }
        $field = 'a.service_id, a.service_type, a.users_id, a.status, a.add_time';
        $field .= ', b.order_code, b.order_status, b.consignee, b.mobile, b.province, b.city, b.district, b.address';
        $field .= ', c.product_name, c.product_price, c.num as product_num, c.litpic as product_img, c.data as product_data';

        // 分页参数
        $Query = request()->param();
        // 查询订单数据
        $result = Db::name('shop_order_service')->alias('a')
            ->field($field)
            ->where($where)
            ->join('__SHOP_ORDER__ b', 'a.order_id = b.order_id', 'LEFT')
            ->join('__SHOP_ORDER_DETAILS__ c', 'a.details_id = c.details_id', 'LEFT')
            ->order('add_time desc, service_id desc')
            ->paginate(15, false, ['query' => $Query]);
        !empty($result) && $serviceData = $result->toArray();
        if (!empty($serviceData['data'])) {
            $orderServiceType = Config::get('global.order_service_type');
            $orderServiceStatus = Config::get('global.order_service_status');
            foreach ($serviceData['data'] as $key => $value) {
                // 添加时间
                $value['add_time'] = date('Y-m-d H:i:s', $value['add_time']);
                // 价格处理
                $value['product_price_arr'] = floatval($value['product_price']) * floatval($value['product_num']);
                $value['product_price_arr'] = explode('.', sprintf("%.2f", $value['product_price_arr']));
                // 商品封面图
                $value['product_img'] = handle_subdir_pic(get_default_pic($value['product_img']));
                // 处理商品规格，组合数据
                $product_data = !empty($value['product_data']) ? unserialize($value['product_data']) : [];
                $value['product_attr'] = !empty($product_data['product_attr']) ? $product_data['product_attr'] : '';
                $value['product_spec'] = !empty($product_data['product_spec']) ? $product_data['product_spec'] : '';
                // 状态处理
                $value['status_name'] = $orderServiceStatus[$value['status']];
                $value['service_type_name'] = $orderServiceType[$value['service_type']];
                // 重载数据
                $serviceData['data'][$key] = $value;
            }
        }

        $this->success('查询成功', null, $serviceData);
    }

    // 查询申请售后的订单商品
    public function getOrderGoodsService($post = [])
    {
        $serviceData = $serviceLog = $expressData = [];
        if (!empty($post['service_id'])) {
            // 如果存在则查询售后服务订单
            $where = [
                'users_id' => $this->users_id,
                'service_id' => $post['service_id'],
            ];
            $serviceData = Db::name('shop_order_service')->where($where)->find();
            if (empty($serviceData)) $this->error('售后订单不存在');

            $serviceData['add_time'] = MyDate('Y-m-d H:i:s', $serviceData['add_time']);
            $serviceData['update_time'] = MyDate('Y-m-d H:i:s', $serviceData['update_time']);
            $serviceData['status_name'] = Config::get('global.order_service_status')[$serviceData['status']];
            $serviceData['refund_way_text'] = 1 === intval($serviceData['refund_way']) ? '退款到余额' : '线下退款';
            $serviceData['service_type_name'] = Config::get('global.order_service_type')[$serviceData['service_type']];
            $serviceData['admin_delivery'] = !empty($serviceData['admin_delivery']) ? unserialize($serviceData['admin_delivery']) : '';
            if (!empty($serviceData['users_delivery']['time'])) {
                $serviceData['users_delivery']['time'] = date('Y-m-d H:i:s', $serviceData['users_delivery']['time']);
            }
            $serviceData['users_delivery'] = !empty($serviceData['users_delivery']) ? unserialize($serviceData['users_delivery']) : '';
            if (!empty($serviceData['admin_delivery']['time'])) {
                $serviceData['admin_delivery']['time'] = date('Y-m-d H:i:s', $serviceData['admin_delivery']['time']);
            }
            // 查询售后订单流程记录
            $where = [
                'service_id' => $post['service_id'],
            ];
            $serviceLog = Db::name('shop_order_service_log')->order('log_id desc')->where($where)->select();
            foreach ($serviceLog as $key => $value) {
                if (!empty($value['users_id'])) {
                    $serviceLog[$key]['name'] = '会员';
                } else if (!empty($value['admin_id'])) {
                    $serviceLog[$key]['name'] = '商家';
                }
                $serviceLog[$key]['add_time'] = MyDate('Y-m-d H:i:s', $value['add_time']);
            }

            // 物流数据表
            $where = [
                'is_choose' => 1,
            ];
            $expressData = Db::name('shop_express')->where($where)->select();

            // 追加参数用于查询
            $post['order_id'] = $serviceData['order_id'];
            $post['details_id'] = $serviceData['details_id'];
            $post['service_id'] = $serviceData['service_id'];
            $post['product_id'] = $serviceData['product_id'];
        }

        // 查询商品
        $where = [
            'a.users_id' => $this->users_id,
            'a.order_id' => $post['order_id'],
            'a.details_id' => $post['details_id'],
            'a.product_id' => $post['product_id']
        ];
        $field = 'b.order_id, b.order_code, b.users_id, b.order_status, b.order_total_amount, b.coupon_price, b.order_amount, b.pay_use_cash, b.pay_use_balance, b.pay_use_scores, b.pay_use_scores_num, b.pay_name, b.pay_time, b.express_time, b.consignee, b.mobile, b.province, b.city, b.district, b.address';
        $field .= ', a.details_id, a.product_id, a.product_name, a.product_price, a.num as product_num, a.data as product_data, a.litpic as product_img, a.apply_service';
        $orderGoods = Db::name("shop_order_details")->alias('a')->join('__SHOP_ORDER__ b', 'a.order_id = b.order_id', 'LEFT')->where($where)->field($field)->find();
        if (empty($orderGoods)) $this->error('订单商品不存在');
        // 处理商品信息
        $orderGoods['product_img'] = $this->get_default_pic($orderGoods['product_img'], true);
        $orderGoods['pay_time'] = !empty($orderGoods['pay_time']) ? MyDate('Y-m-d H:i:s', $orderGoods['pay_time']) : 0;
        $orderGoods['express_time'] = !empty($orderGoods['express_time']) ? MyDate('Y-m-d H:i:s', $orderGoods['express_time']) : 0;
        $orderGoods['pay_name_text'] = !empty($orderGoods['pay_time']) ? Config::get('global.pay_method_arr')[$orderGoods['pay_name']] : '';
        $city = !empty($orderGoods['city']) ? get_city_name($orderGoods['city']) : '';
        $district = !empty($orderGoods['district']) ? get_area_name($orderGoods['district']) : '';
        $province = !empty($orderGoods['province']) ? get_province_name($orderGoods['province']) : '';
        $orderGoods['address'] = $province . ' ' . $city . ' ' . $district . ' ' . $orderGoods['address'];
        $orderGoods['order_status_text'] = Config::get('global.order_status_arr')[$orderGoods['order_status']];
        // 商品规格处理
        $productData = !empty($orderGoods['product_data']) ? unserialize($orderGoods['product_data']): [];
        $productSpec = !empty($productData['product_spec']) ? htmlspecialchars_decode($productData['product_spec']): '';
        $orderGoods['product_spec'] = !empty($productSpec) ? trim($productSpec, '；') : '';
        // 计算商品退款总额
        $orderGoods['refund_price'] = floatval($orderGoods['product_price']) * floatval($orderGoods['product_num']);
        // 如果使用优惠券则计算商品的退款金额
        if (!empty($orderGoods['coupon_price'])) {
            // 计算商品退款总额在订单商品总额中的占比
            $priceRatio = floatval($orderGoods['refund_price']) / floatval($orderGoods['order_total_amount']);
            // 计算商品使用了优惠券的多少金额
            $couponPrice = floatval($priceRatio) * floatval($orderGoods['coupon_price']);
            $orderGoods['use_refund_price'] = unifyPriceHandle($couponPrice);
            // 计算商品退款金额
            $orderGoods['refund_price'] = unifyPriceHandle(floatval($orderGoods['refund_price']) - floatval($couponPrice));
        }
        // 计算商品退款总额在订单实付款总额中的占比
        $priceRatio = floatval($orderGoods['refund_price']) / floatval($orderGoods['order_amount']);
        // 商品退还积分处理 
        $orderGoods['refund_scores'] = 0;
        $orderGoods['refund_balance'] = 0;
        if (!empty($orderGoods['pay_use_scores']) && !empty($orderGoods['pay_use_scores_num'])) {
            // 计算商品要退回多少积分转化的金额
            $orderGoods['refund_scores'] = unifyPriceHandle(floatval($priceRatio) * floatval($orderGoods['pay_use_scores']));
            // 计算商品要退回多少积分
            $orderGoods['refund_scores_num'] = intval(ceil(floatval($priceRatio) * floatval($orderGoods['pay_use_scores_num'])));
        }
        // 商品退还余额处理
        if (!empty($orderGoods['pay_use_balance']) && floatval($orderGoods['pay_use_balance']) > 0) {
            // 计算商品要退回多少余额
            $orderGoods['refund_balance'] = unifyPriceHandle(floatval($priceRatio) * floatval($orderGoods['pay_use_balance']));
        }
        // 商品退还实付款金额处理
        if (!empty($orderGoods['pay_use_cash']) && floatval($orderGoods['pay_use_cash']) > 0) {
            // 计算商品要退回多少余额
            $payUseCash = unifyPriceHandle(floatval($priceRatio) * floatval($orderGoods['pay_use_cash']));
            $orderGoods['refund_balance'] = unifyPriceHandle(floatval($orderGoods['refund_balance']) + floatval($payUseCash));
        }
        // 商品退还余额处理 - 商品要退回多少积分转化的金额
        // if (!empty($orderGoods['refund_scores'])) {
        //     $orderGoods['refund_balance'] = unifyPriceHandle(floatval($orderGoods['refund_balance']) - floatval($orderGoods['refund_scores']));
        // }

        // 后台设置的商家收货地址
        $field = 'contact, mobile, province, city, area, address';
        $address = Db::name('shop_return_address')->field($field)->where(['default' => 1])->find();
        $city = !empty($address['city']) ? get_city_name($address['city']) : '';
        $district = !empty($address['district']) ? get_area_name($address['district']) : '';
        $province = !empty($address['province']) ? get_province_name($address['province']) : '';
        $address['address'] = $province . ' ' . $city . ' ' . $district . ' ' . $address['address'];

        // 可选售后类型
        $serviceType = [
            ['value' => 1, 'name' => '换货', 'checked' => false, 'disabled' => false],
            ['value' => 2, 'name' => '退货退款', 'checked' => false, 'disabled' => false],
            ['value' => 3, 'name' => '仅退款', 'checked' => false, 'disabled' => false]
        ];
        // 待发货订单商品
        if (!empty($orderGoods['order_status']) && 1 === intval($orderGoods['order_status'])) {
            $orderGoods['service_type'] = 3;
            $serviceType[2]['checked'] = true;
            $serviceType[0]['disabled'] = $serviceType[1]['disabled'] = true;
        }
        // 待收货订单商品、已完成订单商品
        else if (!empty($orderGoods['order_status']) && in_array($orderGoods['order_status'], [2, 3])) {
            $orderGoods['service_type'] = 0;
            $serviceType[2]['disabled'] = true;
        }

        // 判断申请的商品是否是订单内最后一个可申请维权的商品，如果是则默认标记退还优惠券
        $orderGoods['refund_coupon'] = 0;
        $where = [
            'apply_service' => 0,
            'users_id' => $this->users_id,
            'order_id' => $post['order_id'],
        ];
        $applyServiceCount = Db::name('shop_order_details')->where($where)->count();
        if (!empty($applyServiceCount) && 1 === intval($applyServiceCount)) $orderGoods['refund_coupon'] = 1;

        // 整合返回数据
        $result = [
            // 商家收货地址
            'address' => !empty($address) ? $address : [],
            // 可选物流公司
            'express' => !empty($expressData) ? $expressData : [],
            // 申请售后订单商品
            'orderGoods' => !empty($orderGoods) ? $orderGoods : [],
            // 申请售后服务数据
            'service' => !empty($serviceData) ? $serviceData : [],
            // 申请售后服务记录
            'serviceLog' => !empty($serviceLog) ? $serviceLog : [],
            // 可选售后类型
            'serviceType' => !empty($serviceType) ? $serviceType : [],
        ];
        $this->success('查询成功', null, $result);
    }

    // 添加申请售后的订单商品入库
    public function addOrderGoodsService($post = [])
    {
        // 解析参数
        $formData = !empty($post['submitForm']) ? htmlspecialchars_decode($post['submitForm']) : '';
        $formData = json_decode(htmlspecialchars_decode($formData), true);

        // 查询是否已申请售后
        $where = [
            'users_id' => $this->users_id,
            'order_id' => $formData['order_id'],
            'product_id' => $formData['product_id'],
            'details_id' => $formData['details_id']
        ];
        $service = Db::name('shop_order_service')->where($where)->find();
        if (!empty($service) && !in_array($service['status'], [3, 8, 9])) $this->error('商品已申请维权');

        $time = getTime();
        // 维权订单被拒接或被关闭时重新申请则延用之前
        if (!empty($service) && in_array($service['status'], [3, 8, 9])) {
            $update = [
                'service_type' => !empty($formData['service_type']) ? intval($formData['service_type']) : 0,
                'content' => !empty($formData['content']) ? htmlspecialchars($formData['content']) : '',
                'refund_price' => !empty($formData['refund_price']) ? floatval($formData['refund_price']) : 0,
                'actual_price' => !empty($formData['refund_price']) ? floatval($formData['refund_price']) : 0,
                'refund_code' => 'HH' . $time . rand(10, 100),
                'refund_coupon' => !empty($formData['refund_coupon']) ? intval($formData['refund_coupon']) : 0,
                'status' => 1,
                'audit_time' => 0,
                'users_delivery' => '',
                'add_time' => $time,
                'update_time' => $time,
            ];
            if (2 == $update['service_type'] && !empty($update['refund_price'])) $update['refund_code'] = 'TKTH' . $time . rand(10, 100);
            if (3 == $update['service_type'] && !empty($update['refund_price'])) $update['refund_code'] = 'JTK' . $time . rand(10, 100);
            $updateID = Db::name('shop_order_service')->where($where)->update($update);
            $serviceID = !empty($updateID) ? intval($service['service_id']) : 0;
        }
        // 新添加的维权订单
        else if (empty($service)) {
            $insert = [
                'service_type' => !empty($formData['service_type']) ? intval($formData['service_type']) : 0,
                'users_id' => intval($this->users_id),
                'order_id' => !empty($formData['order_id']) ? intval($formData['order_id']) : 0,
                'details_id' => !empty($formData['details_id']) ? intval($formData['details_id']) : 0,
                'product_id' => !empty($formData['product_id']) ? intval($formData['product_id']) : 0,
                'refund_way' => 1,
                'refund_price' => !empty($formData['refund_price']) ? floatval($formData['refund_price']) : 0,
                'refund_balance' => !empty($formData['refund_balance']) ? floatval($formData['refund_balance']) : 0,
                'refund_scores' => !empty($formData['refund_scores']) ? floatval($formData['refund_scores']) : 0,
                'refund_scores_num' => !empty($formData['refund_scores_num']) ? intval($formData['refund_scores_num']) : 0,
                'actual_price' => !empty($formData['refund_balance']) ? floatval($formData['refund_balance']) : 0,
                'refund_code' => 'HH' . $time . rand(10, 100),
                'refund_coupon' => !empty($formData['refund_coupon']) ? intval($formData['refund_coupon']) : 0,
                'content' => !empty($formData['content']) ? htmlspecialchars($formData['content']) : '',
                'status' => 1,
                'audit_time' => 0,
                'users_delivery' => '',
                'admin_delivery' => '',
                'add_time' => $time,
                'update_time' => $time,
            ];
            if (2 == $insert['service_type'] && !empty($insert['refund_price'])) $insert['refund_code'] = 'TKTH' . $time . rand(10, 100);
            if (3 == $insert['service_type'] && !empty($insert['refund_price'])) $insert['refund_code'] = 'JTK' . $time . rand(10, 100);
            $serviceID = Db::name('shop_order_service')->insertGetId($insert);
        }

        // 申请售后后续操作
        if (!empty($serviceID)) {
            // 更新订单明细表中对应商品为申请服务
            $update = [
                'details_id' => $formData['details_id'],
                'apply_service' => 1,
                'update_time' => getTime()
            ];
            Db::name('shop_order_details')->update($update);

            // 添加订单服务记录
            $logNote = '提交换货申请！';
            if (2 == $formData['service_type']) $logNote = '提交退货退款申请！';
            if (3 == $formData['service_type']) $logNote = '提交退款申请！';
            // 追加申请说明
            $content = !empty($formData['content']) ? htmlspecialchars($formData['content']) : '';
            $logNote .= !empty($content) ? '(维权描述：' . $content . ')' : '';
            orderServiceLog($serviceID, $formData['order_id'], $this->users_id, 0, $logNote);

            // 申请成功返回
            $this->success('已提交申请');
        } else {
            $this->error('操作失败，刷新重试');
        }
    }

    // 取消售后订单
    public function cancelOrderGoodsService($post = [])
    {
        // 取消服务单
        $times = getTime();
        $where = [
            'users_id' => $this->users_id,
            'service_id' => $post['service_id']
        ];
        $update = [
            'status' => 8,
            'audit_time' => 0,
            'update_time' => $times,
        ];
        $resultID = Db::name('shop_order_service')->where($where)->update($update);
        if (!empty($resultID)) {
            // 更新订单明细表中对应商品为未申请服务
            $where = [
                'users_id' => $this->users_id,
                'order_id' => $post['order_id'],
                'details_id' => $post['details_id']
            ];
            $update = [
                'apply_service' => 0,
                'update_time' => $times
            ];
            Db::name('shop_order_details')->where($where)->update($update);

            // 添加记录单
            $post['status'] = 8;
            $this->addOrderServiceLog($post);

            $this->success('取消成功');
        } else {
            $this->error('取消失败');
        }
    }

    // 添加售后订单会员邮寄物流信息
    public function addServiceUsersDelivery($post = [])
    {
        // 解析物流参数
        $usersDelivery = htmlspecialchars_decode($post['usersDelivery']);
        $usersDelivery = json_decode(htmlspecialchars_decode($usersDelivery), true);
        $usersDelivery['time'] = getTime();

        // 更新处理
        $where = [
            'users_id' => $this->users_id,
            'service_id' => $post['service_id'],
        ];
        $update = [
            'status' => 4,
            'users_delivery' => !empty($usersDelivery) ? serialize($usersDelivery) : '',
            'update_time' => getTime(),
        ];
        $resultID = Db::name('shop_order_service')->where($where)->update($update);
        if (!empty($resultID)) {
            // 添加记录单
            $post['status'] = 4;
            $this->addOrderServiceLog($post);

            $this->success('提交物流成功');
        } else {
            $this->error('提交物流失败');
        }
    }

    // 买家确认收到商品
    public function confirmOrderGoodsService($post = [])
    {
        $times = getTime();
        $where = [
            'users_id' => $this->users_id,
            'service_id' => $post['service_id']
        ];
        $update = [
            'status' => 7,
            'update_time' => $times,
        ];
        $resultID = Db::name('shop_order_service')->where($where)->update($update);
        if (!empty($resultID)) {
            // 添加记录单
            $post['status'] = 7;
            $this->addOrderServiceLog($post);

            $this->success('操作成功');
        } else {
            $this->error('操作失败');
        }
    }

    // 记录商品退换货服务单信息
    public function addOrderServiceLog($post = [])
    {
        if (empty($post)) return false;
        // 维权类型
        $service_type = '';
        if (!empty($post['service_type']) && 1 === intval($post['service_type'])) {
            $service_type = '换货';
        } else if (!empty($post['service_type']) && 2 === intval($post['service_type'])) {
            $service_type = '退货退款';
        } else if (!empty($post['service_type']) && 3 === intval($post['service_type'])) {
            $service_type = '退款';
        }
        // 操作事由
        if (2 === intval($post['status'])) {
            $logNote = '同意' . $service_type . '申请！';
        } else if (3 === intval($post['status'])) {
            $logNote = '拒绝' . $service_type . '申请！';
        } else if (4 === intval($post['status'])) {
            $logNote = '已退货，商家待收货！';
        } else if (5 === intval($post['status']) && 1 === intval($post['service_type'])) {
            $logNote = '已收到退货，待重新发货！';
        } else if (5 === intval($post['status']) && 2 === intval($post['service_type'])) {
            $logNote = '已收到退货，待转账！';
        } else if (6 === intval($post['status'])) {
            $logNote = '已重新发货，买家待收货！';
        } else if (7 === intval($post['status']) && 1 === intval($post['service_type'])) {
            $logNote = '买家已确认收货，' . $service_type . '维权完成！';
        } else if (7 === intval($post['status']) && in_array($post['service_type'], [2, 3])) {
            $logNote = $service_type . '维权完成！';
        } else if (8 === intval($post['status'])) {
            $logNote = '关闭' . $service_type . '申请！';
        } else if (9 === intval($post['status'])) {
            $logNote = '已拒绝收货，请与买家联系处理！';
        }
        orderServiceLog($post['service_id'], $post['order_id'], $this->users_id, 0, $logNote);
    }
}